//
//  MatchmakingServer.m
//  ProjectW
//
//  Created by Nguyen Tan Loc on 7/21/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "MatchmakingServer.h"

@implementation MatchmakingServer


@synthesize maxClients = _maxClients;
@synthesize session = _session;
@synthesize connectedClients = _connectedClients;
@synthesize delegate = _delegate;

-(id) init
{
    if (self = [super init])
    {
        _serverState = ServerStateIdle;
    }
    return self;
}

-(void) startAcceptingConnectionForSessionID:(NSString *)sessionID
{
    if (_serverState == ServerStateIdle)
    {
        _serverState = ServerStateAcceptingConnections;
        _connectedClients = [NSMutableArray arrayWithCapacity:self.maxClients];
        
        _session = [[GKSession alloc] initWithSessionID:sessionID displayName:nil sessionMode:GKSessionModeServer];
        _session.delegate = self;
        _session.available = YES;
    }
}

-(int) getConnectedClientCount
{
    return [_connectedClients count];
}

-(NSString*) getPeerIDForConnectedClientAtIndex:(int)index
{
    return [_connectedClients objectAtIndex:index];
}

-(NSString*) getDisplayNameForPeerID:(NSString *)peerID
{
    return [_session displayNameForPeer:peerID];
}

-(void) session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
    NSLog(@"MatchmakingClient: peer %@ changed state %d", peerID, state);
    
    switch (state) {
        case GKPeerStateAvailable:
            break;
        case GKPeerStateUnavailable:
            break;
        case GKPeerStateConnecting:
            break;
        case GKPeerStateConnected: // Client has connected to the server
            if (_serverState == ServerStateAcceptingConnections)
            {
                if (![_connectedClients containsObject:peerID])
                {
                    [_connectedClients addObject:peerID];
                    [_delegate matchmakingServer:self clientDidConnect:peerID];
                }
            }
            break;
        case GKPeerStateDisconnected: // Client has disconnected from the server
            if (_serverState == ServerStateAcceptingConnections)
            {
                if ([_connectedClients containsObject:peerID])
                {
                    [_connectedClients removeObject:peerID];
                    [_delegate matchmakingServer:self clientDidDisconnect:peerID];
                }
            }
            break;
        default:
            break;
    }
}

-(void) session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID
{
    NSLog(@"MatchmakingClient: connection request from peer %@", peerID);
    
    if (_serverState == ServerStateAcceptingConnections && [self getConnectedClientCount] < self.maxClients)
    {
        NSError *error;
        if ([_session acceptConnectionFromPeer:peerID error:&error])
            ;
        else 
            ;
    }
    else 
    {
        [_session denyConnectionFromPeer:peerID];
    }
}

-(void) session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error
{
    NSLog(@"MatchmakingClient: connection with peer %@ failed %@", peerID, error);
}

-(void) session:(GKSession *)session didFailWithError:(NSError *)error
{
    NSLog(@"MatchmakingClient: session failed %@", error);
    
    if ([[error domain] isEqualToString:GKSessionErrorDomain])
    {
        if ([error code] == GKSessionCannotEnableError)
        {
            [_delegate matchmakingServerNoNetwork:self];
            [self endSession];
        }
    }
}

-(void) endSession
{
    _serverState = ServerStateIdle;
    
    [_session disconnectFromAllPeers];
    _session.available = NO;
    _session.delegate = nil;
    _session = nil;
    
    _connectedClients = nil;
    
    [_delegate matchmakingServerSessionDidEnd:self];
}

@end
